package org.fusionide.builder.parsers.cfml.tags;

import java.util.Vector;

import org.fusionide.builder.parsers.IParserHandler;
import org.fusionide.builder.parsers.ParserException;
import org.fusionide.builder.parsers.cfml.CFMLTag;
import org.fusionide.builder.parsers.cfml.Variable;


public class Argument extends CFMLTag {
	// <cfargument name="" required="" type="" hint="" displayname=""
	// default="">

	private String name;

	private String required;

	private String type;

	private String hint;

	private String displayName;

	private String defaultValue;

	public Argument(String attributes, int lineNumber) {
		super(attributes, lineNumber);

		if (attributes == null)
			return;

		this.name = getAttribute("name");
		this.required = getAttribute("required");
		this.type = getAttribute("type");
		this.hint = getAttribute("hint");
		this.displayName = getAttribute("displayname");
		this.defaultValue = getAttribute("defaultvalue");
	}

	@Override
	public boolean validate(IParserHandler parserHandler) {
		if (super.validate(parserHandler)) {
			if (getName() == null || getName().equalsIgnoreCase("")) {
				if (parserHandler != null)
					parserHandler.addMarker(new ParserException("<cfargument> Name attribute is required", ParserException.SEVERITY_ERROR, getStartLine()));
				return false;
			}

			if (getRequired() != null && getRequired().matches("yes|true") && getDefaultValue() != null) {
				if (parserHandler != null)
					parserHandler.addMarker(new ParserException(
							"<cfargument> Required attribute set to true, but has a default value",
							ParserException.SEVERITY_WARNING,
							getStartLine()));
				return false;
			}
			return true;
		} else {
			return false;
		}
	}

	@Override
	public boolean requiresClosingTag() {
		return false;
	}

	@Override
	public boolean acceptsChildren(CFMLTag tag) {
		return false;
	}

	@Override
	public boolean setParent(CFMLTag parent) {
		if (!(parent instanceof Function))
			return false;
		return super.setParent(parent);
	}

	@Override
	public Vector<Variable> getVariables(int offset) {
		Vector<Variable> vars = new Vector<Variable>();
		if (offset <= getEndOffset())
			return vars;
		if (validate(null)) {
			Variable var = new Variable("arguments." + getName(), getEndLine(), true, Variable.getType(getType()));
			var.setHint(getDefaultValue());
			vars.add(var);
		}
		return vars;
	}

	public String getDisplayName() {
		return displayName;
	}

	public void setDisplayName(String displayName) {
		this.displayName = displayName;
	}

	public String getHint() {
		return hint;
	}

	public void setHint(String hint) {
		this.hint = hint;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getRequired() {
		return required;
	}

	public void setRequired(String required) {
		this.required = required;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getDefaultValue() {
		return defaultValue;
	}

	public void setDefaultValue(String defaultValue) {
		this.defaultValue = defaultValue;
	}

	public String toString() {
		// <cfargument name="" required="" type="" hint="" displayname=""
		// default="">
		StringBuffer sb = new StringBuffer();
		sb.append("<cfargument");
		sb.append(" name=\"" + name + "\"");
		if (required != null)
			sb.append(" required=\"" + required + "\"");
		if (type != null)
			sb.append(" type=\"" + type + "\"");
		if (hint != null)
			sb.append(" hint=\"" + hint + "\"");
		if (displayName != null)
			sb.append(" displayname=\"" + displayName + "\"");
		if (defaultValue != null)
			sb.append(" default=\"" + defaultValue + "\"");

		sb.append("/>");
		return sb.toString();
	}
}
